package qq2564874169.tuaotuao.fx;

import java.util.*;

public class StringKeyMap<V> implements Map<String, V> {
    Map<K, V> data = new LinkedHashMap<>();

    public StringKeyMap(Map<? extends String, ? extends V> data) {
        if (data != null) {
            putAll(data);
        }
    }

    public StringKeyMap() {


    }

    @Override
    public int size() {
        return data.size();
    }

    @Override
    public boolean isEmpty() {
        return data.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        return data.containsKey(new K(key));
    }

    @Override
    public boolean containsValue(Object value) {
        return data.containsValue(value);
    }

    @Override
    public V get(Object key) {
        return data.get(new K(key));
    }

    @Override
    public V put(String key, V value) {
        return data.put(new K(key), value);
    }

    @Override
    public V remove(Object key) {
        return data.remove(new K(key));
    }

    @Override
    public void putAll(Map<? extends String, ? extends V> m) {
        for (String k : m.keySet()) {
            put(k, m.get(k));
        }
    }

    @Override
    public void clear() {
        data.clear();
    }

    @Override
    public Set<String> keySet() {
        Set<String> set = new LinkedHashSet<>();
        for (K k : data.keySet()) {
            set.add(k.raw);
        }
        return set;
    }

    @Override
    public Collection<V> values() {
        return data.values();
    }

    @Override
    public Set<Entry<String, V>> entrySet() {
        Set<Entry<String, V>> set = new LinkedHashSet<>();
        for (K k : data.keySet()) {
            set.add(new MapEntry(this, k));
        }
        return set;
    }

    @Override
    public String toString() {
        return data.toString();
    }

    @Override
    public int hashCode() {
        return data.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return data.equals(obj);
    }

    static class MapEntry<V> implements Entry<String, V> {
        private K key;
        private StringKeyMap<V> map;

        MapEntry(StringKeyMap<V> map, K key) {
            this.map = map;
            this.key = key;
        }

        @Override
        public String getKey() {
            return key.raw;
        }

        @Override
        public V getValue() {
            return map.data.get(key);
        }

        @Override
        public V setValue(V value) {
            return map.data.put(key, value);
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof MapEntry) {
                MapEntry me = (MapEntry) obj;
                if (me.key.equals(key)) {
                    if (me.getValue() == null && getValue() == null) {
                        return true;
                    }
                    if (me.getValue() != null) {
                        return me.getValue().equals(getValue());
                    }
                }
            }
            return false;
        }

        @Override
        public int hashCode() {
            return key.hashCode();
        }
    }

    private static class K {
        public final String raw;
        private int code;

        public K(Object s) {
            raw = s.toString();
            code = raw.toLowerCase().hashCode();
        }

        @Override
        public String toString() {
            return raw;
        }

        @Override
        public int hashCode() {
            return code;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof K) {
                return raw.equalsIgnoreCase(((K) obj).raw);
            }
            return false;
        }
    }
}
